package mvc_generator.generator;

import java.util.ArrayList;
import java.util.List;

import javax.swing.text.html.FormView;

import mvc_generator.mVCGenerator.AssignedField;
import mvc_generator.mVCGenerator.BooleanType;
import mvc_generator.mVCGenerator.Controller;
import mvc_generator.mVCGenerator.Declaration;
import mvc_generator.mVCGenerator.DoubleType;
import mvc_generator.mVCGenerator.Form;
import mvc_generator.mVCGenerator.FormValidation;
import mvc_generator.mVCGenerator.IntegerType;
import mvc_generator.mVCGenerator.ModelMVC;
import mvc_generator.mVCGenerator.SimpleType;
import mvc_generator.mVCGenerator.View;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;

/**
 * Here are the function we use for commodity.
 * 
 * @author Jean-Luc Amitousa Mankoy
 */
public class MVCGeneratorGeneratorUtils {

	public static void print(String str){
		System.out.println(str);
	}
	
	/**
	 * Match the first container with the wanted class
	 * 
	 * @param eo
	 *            the contained object
	 * @param containerClazz
	 *            the class wanted
	 * @return the found container
	 */
	public static <T> T findContainer(EObject eo, Class<T> containerClazz) {
		EObject container = null;
		EObject tmpObject = eo;
		Boolean objectClassTreated = false;

		do {
			if (containerClazz.isInstance(tmpObject)) {
				container = tmpObject;
				break;
			}

			if (containerClazz == Object.class) {
				objectClassTreated = true;
			}

			tmpObject = tmpObject.eContainer();

		} while (objectClassTreated == false);

		return (T) container;
	}
	
	/**
	 * Match the ModelMVC container
	 * 
	 * @param eo
	 *            the contained object
	 * @return the found ModelMVC
	 */
	public static ModelMVC findModelMVCContainer(EObject eo) {
		return (ModelMVC) findContainer(eo, ModelMVC.class);
	}

	/**
	 * Match the View container
	 * 
	 * @param eo
	 *            the contained object
	 * @return the found WebSite
	 */
	public static View findViewContainer(EObject eo) {
		return (View) findContainer(eo, View.class);
	}

	/**
	 * Want you set a var i in a CharSequence like this : ''' <<FOR String s :
	 * strings>> //do something <<i= i +1>> <<ENDFOR>> The i var is displayed.
	 * '''
	 * 
	 * If you want it to avoid that you can do this : ''' <<FOR String s :
	 * strings>> //do something <<MVCGeneratorGeneratorUtils.toVoidExpr(i= i
	 * +1)>> <<ENDFOR>> '''
	 * 
	 * @param o
	 */
	public static void toVoidExpr(Object o) {
		// It work without do nothing
	}

	/**
	 * @param listObjs
	 * @param clazz
	 *            the clazz matching-objects are instance of.
	 * @return
	 */
	public static <T, P> List<T> filter(EList<P> listObjs, Class<T> clazz) {
		List<T> matchingObjs = new ArrayList<T>();

		for (P eo : listObjs) {
			if (clazz.isInstance(eo)) {
				matchingObjs.add((T) eo);
			}
		}

		return matchingObjs;
	}

	public static void fileUriToQualifiedName(String fileURI) {
		// file:
	}

	// Boris's section

	public static Form getValidateForm(FormValidation fv){
		Form form= null;
		Controller controllerContainer= 
				MVCGeneratorGeneratorUtils.findContainer(fv, Controller.class);

		for(Form tmpForm : controllerContainer.getControlledView().getForms()){
			if(tmpForm.getName().compareTo(fv.getValidatedFormName())==0){
				form = tmpForm;
				break;
			}
		}

		return form;
	}

	public static FormValidation getValidator(Form form){
		FormValidation fv= null;

		// The view that contains the form
		View viewContainer = MVCGeneratorGeneratorUtils.findContainer(form, View.class);

		// The controller that control viewContainer
		Controller viewController = null;

		for (Controller tmpController : MVCGeneratorGeneratorUtils
				.findContainer(form, ModelMVC.class).getControllers()) {

			if (tmpController.getControlledView().getName()
					.compareTo(viewContainer.getName()) == 0) {
				viewController = tmpController;
			}
		}

	
		for(FormValidation tmpFV : viewController.getFormValidations()){
			if(tmpFV.getValidatedFormName().compareTo(form.getName())==0){
				fv = tmpFV;
				break;
			}
		}
		
		if(fv==null){
			System.out.println("no fv found bitch !!!!");
		}
		
		return fv;
	}
	
	public static SimpleType getSimpleTypeOfAssignement(
			AssignedField assignedField) {

		// The view that contains assignedField
		View viewContainer = MVCGeneratorGeneratorUtils.findContainer(
				assignedField, View.class);

		// The controller that control viewContainer
		Controller viewController = null;

		for (Controller tmpController : MVCGeneratorGeneratorUtils
				.findContainer(assignedField, ModelMVC.class).getControllers()) {
			if (tmpController.getControlledView().getName()
					.compareTo(viewContainer.getName()) == 0) {
				viewController = tmpController;
			}
		}

		for (Declaration d : viewController.getDeclarations()) {
			if (d.getName().equals(assignedField.getFieldName())) {
				return d.getType();
			}
		}

		return null;
	}

	public static String getInitialValue(SimpleType st) {

		if (st instanceof IntegerType || st instanceof DoubleType) {
			return "0";
		}
		if (st instanceof BooleanType) {
			return "false";
		}
		return "null";

	}

	public static void copyDir(URI srcDirURI, URI destDirURI) throws Exception {

		// System.out.println();
		// File srcDir= null;//new File(srcDirURI);
		// File destDir= null; //new File(destDirURI);
		// String[] srcStrFiles= srcDir.list();
		// InputStream in= null;
		// OutputStream out= null;
		//
		// try{
		// System.out.println(srcDir.getAbsolutePath());
		// for(String srcStrFile : srcStrFiles){
		// File srcFile= new File(srcDir, srcStrFile);
		// File destFile= new File(destDir, srcStrFile);
		//
		// in= new FileInputStream(srcFile);
		// out= new FileOutputStream(destFile);
		//
		// byte[] buffer= new byte[1024];
		// int lenght= 0;
		//
		// while((lenght = in.read(buffer)) > 0){
		// out.write(buffer, 0, lenght);
		// }
		// }
		// }
		// catch(Exception e){
		// throw e;
		// }
		// finally {
		// if(in != null){
		// in.close();
		// }
		//
		// if(out != null){
		// out.close();
		// }
		// }
	}
}
